package ysq.xyg.wxapi.controller;

import com.github.pagehelper.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import ysq.xyg.base.controller.BaseController;
import ysq.xyg.base.util.BaseConstant;
import ysq.xyg.base.util.BaseUtil;
import ysq.xyg.base.util.ProProperties;
import ysq.xyg.web.model.po.WebAccount;
import ysq.xyg.web.model.po.WebMember;
import ysq.xyg.web.service.WebMemberService;
import ysq.xyg.wxapi.api.WxApiClient;
import ysq.xyg.wxapi.api.WxMemoryCacheClient;
import ysq.xyg.wxapi.model.base.OAuthAccessToken;
import ysq.xyg.wxapi.model.base.OAuthScope;
import ysq.xyg.wxapi.model.base.User;
import ysq.xyg.wxapi.url.WxUrlUtil;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Date;

/**
 * 微信端controller层
 *
 * @author shengQiang yu
 * @date 2019-4-26 11:34:01
 */
@Controller
@RequestMapping("/weiXin")
public class WeXinController extends BaseController {
    private static final Logger log= LoggerFactory.getLogger(WeXinController.class);

    @Autowired
    private WebMemberService webMemberService;

    /**
     * oauth2.0跳转入库
     * */
    @RequestMapping("/oauth1")
    public ModelAndView oauth(HttpServletResponse response, HttpServletRequest request) throws IOException {
        String oauthType = request.getParameter("oauthType");
        String params = request.getParameter("params");
        String path = request.getParameter("path");
        String pathParams = request.getParameter("pathParams");
        String scope= OAuthScope.Base.toString();
        if(OAuthScope.Userinfo.toString().equals(oauthType)){
            scope= OAuthScope.Userinfo.toString();
        }
        //获取缓存中的唯一账号
        WebAccount wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();
        String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppId(), wxAccountInfo.getBaseUrl()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams,scope);
        return new ModelAndView("redirect:" + url);
    }

    /**
     * 获取openid 并跳转
     * */
    @RequestMapping("/acceptOpenid")
    public ModelAndView acceptOpenid(HttpServletResponse response, HttpServletRequest request) throws IOException {
        String code = request.getParameter("code");
        // 获取到的state是模式页面组合，模式由一个字符，1表示base,2表示userinfo,其他为页面标识符
        String scope = request.getParameter("state");
        String params = request.getParameter("params");
        String path = request.getParameter("path");
        String pathParams = request.getParameter("pathParams");
        if("null".equals(params)){
            params="";
        }
        if("null".equals(path)){
            path="";
        }
        if("null".equals(pathParams)){
            pathParams="";
        }
        ModelAndView modelAndView=null;
        try {
            // 获取缓存中的唯一账号
            WebAccount wxAccountInfo = WxMemoryCacheClient.getSingleWxAccountInfo();
            OAuthAccessToken oAuthAccessToken = WxApiClient.getOAuthOpenId(wxAccountInfo, code);
            log.info("openid is "+oAuthAccessToken.getOpenid());
            if (StringUtils.isEmpty(oAuthAccessToken.getOpenid())) {
                //跳转到oauth2.0的url
                String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppId(), wxAccountInfo.getBaseUrl()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams, OAuthScope.Base.toString());
                modelAndView =  new ModelAndView("redirect:" + url);
            }else{
                //判断当前用户是否已经保存到数据库
                WebMember member = createUser(oAuthAccessToken,scope,params);
                if (member != null) {
                    String url="";
                    if(StringUtil.isNotEmpty(path)&&!("null".equalsIgnoreCase(path))){
                        url=path+"?memberId="+member.getId();
                        if(StringUtil.isNotEmpty(pathParams)&&!("null".equalsIgnoreCase(pathParams))){
                            String[] t=pathParams.split(",");
                            for (String c:t){
                                String[] k=c.split("\\*");
                                url+="&"+k[0]+"="+k[1];
                            }
                        }
                    }
                    modelAndView = acceptView(params,member,url);
                } else {
                    //跳转到oauth2.0的url
                    String url = WxUrlUtil.getOAuthCodeUrl(wxAccountInfo.getAppId(), wxAccountInfo.getBaseUrl()+ ProProperties.getInstance().getWxOauthAcceptOpenidURL()+"?params="+params+"&path="+path+"&pathParams="+pathParams, OAuthScope.Userinfo.toString());
                    modelAndView =  new ModelAndView("redirect:" + url);
                }
                return modelAndView;
            }
        } catch (Exception e) {
            //跳转错误页面
            e.printStackTrace();
        }
        return modelAndView;
    }


    protected ModelAndView acceptView(String params, WebMember member, String url){
        ModelAndView modelAndView=null;
        if(StringUtil.isNotEmpty(url)) {
            //参数页面
            modelAndView = new ModelAndView("redirect:" + url);
        }else{
            //默认页面
            modelAndView = new ModelAndView("redirect:"+ ProProperties.getInstance().getWxOauthRredirectIndexURL(member.getId()));
        }
        return  modelAndView;
    }

    /**
     * 创建本地用户
     * @return
     */
    protected WebMember createUser(OAuthAccessToken oAuthAccessToken, String scope, String params){
        WebMember member=webMemberService.selectEntityByOpenid(oAuthAccessToken.getOpenid());
        if(member == null){
            // 用户不存在
            if(BaseConstant.OAUTH_USERINFO.equals(scope)){
                //Oauth为获取用户信息模式
                User user= WxApiClient.getOAuthUserInfo(oAuthAccessToken);
                if(user!=null){
                    //将用户信息插入数据库
                    member=new WebMember();
                    int cardNo = webMemberService.selectMaxId();
                    if (cardNo < BaseConstant.MEMBER_MIN_DEFAULT_ID) {
                        cardNo = BaseConstant.MEMBER_MIN_DEFAULT_ID;
                    } else {
                        cardNo = cardNo + 1;
                    }
                    member.setId(BaseUtil.uId());
                    member.setCardNo(String.valueOf(cardNo));
                    member.setOpenid(user.getOpenid());
                    member.setCreditScore(100);
                    member.setHeadImage(user.getHeadimgurl());
                    member.setNickName(BaseUtil.encodeBase64String(user.getNickname()));
                    member.setRemoveTag(BaseConstant.BASE_REMOVE_TAG_NORMAL);
                    member.setCreateTime(new Date());
                    member.setGrade("1");
                    member.setUnionid(user.getUnionid());
                    member.setMoney(0.0);
                    if(StringUtil.isNotEmpty(params)){
                        WebMember parent=webMemberService.selectEntityByCardNo(params);
                        if(parent!=null){
                            member.setOneCardNo(parent.getCardNo());
                            member.setTwoCardNo(parent.getOneCardNo());
                            member.setAreaCardNo(parent.getAreaCardNo());
                        }
                    }
                    int ids=webMemberService.insert(member);
                    if(ids>0){
                        return member;
                    }
                }
            }
            return null;
        }else{
            //用户存在
            return member;
        }
    }

    //从输入流读取post参数
    protected String readStreamParameter(ServletInputStream in){
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader=null;
        try{
            reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));
            String line=null;
            while((line = reader.readLine())!=null){
                buffer.append(line);
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            if(null!=reader){
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return buffer.toString();
    }
}
